package no.priv.garshol.duke.utils; import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.Map; import java.util.Set; import java.util.List; import java.util.HashMap; import java.util.HashSet; import java.util.ArrayList; import java.io.IOException; import java.net.URL; import java.net.URLEncoder; import java.net.URLConnection; import java.net.HttpURLConnection; import org.xml.sax.XMLReader; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.helpers.XMLReaderFactory; import org.xml.sax.helpers.DefaultHandler; public class SparqlClient { private static final String SPARQL_NS = "http://www.w3.org/2005/sparql-results#"; public static SparqlResult execute(String endpoint, String query, String username, String password) { query = urlencode(query); String url = endpoint + "?query=" + query; return loadResultSet(getResponse(url, username, password)); } public static SparqlResult loadResultSet(InputSource source) { try { ResultHandler handler = new ResultHandler(); XMLReader parser = XMLReaderFactory.createXMLReader(); parser.setContentHandler(handler); parser.parse(source); return handler.getResults(); } catch (IOException e) { throw new RuntimeException(e); } catch (SAXException e) { throw new RuntimeException(e); } } private static InputSource getResponse(String url, String username, String password) { try { URL urlobj = new URL(url); HttpURLConnection conn = (HttpURLConnection) urlobj.openConnection(); // Basic Authentication if (username != null && password != null) { byte[] buf = (username + ":" + password).getBytes("utf-8"); String encoding = new sun.misc.BASE64Encoder().encode(buf); conn.setRequestProperty("Authorization", "Basic " + encoding); } conn.setRequestProperty("Accept", "application/sparql-results+xml"); return new InputSource(conn.getInputStream()); } catch (IOException e) { throw new RuntimeException(e); } } private static String urlencode(String url) { try { return URLEncoder.encode(url, "utf-8"); } catch (IOException e) { throw new RuntimeException(e); } } private static class ResultHandler extends DefaultHandler { private SparqlResult result; private String[] currentRow; private Map<String, Integer> columnIndexes; private int colix; private String curvar; private Set<String> keepers; private boolean keep; private StringBuffer content; private ResultHandler() { this.result = new SparqlResult(); this.columnIndexes = new HashMap(); this.colix = 0; this.keepers = new HashSet(); this.content = new StringBuffer(); keepers.add("uri"); keepers.add("literal"); keepers.add("bnode"); } public SparqlResult getResults() { return result; } public void startElement(String uri, String localName, String qName, Attributes attributes) { if (!SPARQL_NS.equals(uri)) return; // not SPARQL namespace, so we don't know what it is if (localName.equals("variable")) { String var = attributes.getValue("name"); columnIndexes.put(var, colix++); result.addVariable(var); } else if (localName.equals("result")) currentRow = new String[columnIndexes.size()]; else if (localName.equals("binding")) curvar = attributes.getValue("name"); else if (keepers.contains(localName)) { keep = true; content.setLength(0); } } public void characters(char[] ch, int start, int length) { if (keep) content.append(ch, start, length); } public void endElement(String uri, String localName, String qName) { if (!SPARQL_NS.equals(uri)) return; // not SPARQL namespace, so we don't know what it is if (localName.equals("binding")) { int ix = columnIndexes.get(curvar); currentRow[ix] = content.toString(); } else if (localName.equals("result")) result.addRow(currentRow); else if (keepers.contains(localName)) keep = false; } } }